package cn.wolfcode.service.impl;

import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.domain.AccountLog;
import cn.wolfcode.domain.AccountTransaction;
import cn.wolfcode.domain.OperateIntergralVo;
import cn.wolfcode.mapper.AccountLogMapper;
import cn.wolfcode.mapper.AccountTransactionMapper;
import cn.wolfcode.mapper.UsableIntegralMapper;
import cn.wolfcode.service.IUsableIntegralService;
import cn.wolfcode.web.msg.IntergralCodeMsg;
import com.alibaba.fastjson.JSON;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;


@Service
@Slf4j
public class UsableIntegralServiceImpl implements IUsableIntegralService {
    @Autowired
    private UsableIntegralMapper usableIntegralMapper;
    @Autowired
    private AccountTransactionMapper accountTransactionMapper;
    @Autowired
    private AccountLogMapper accountLogMapper;


    @Override
    @Transactional
    public void decrIntergral(OperateIntergralVo operateIntergralVo) {
        // 1 往日志表里去插入数据 t_acount_log
        AccountLog accountLog = new AccountLog();
        accountLog.setAmount(operateIntergralVo.getValue()); // 此次积分变动数值
        accountLog.setGmtTime(new Date());                   // 日志插入时间
        accountLog.setInfo(operateIntergralVo.getInfo());    // 备注信息
        accountLog.setPkValue(operateIntergralVo.getPk());   // 业务主键
        accountLog.setType(AccountLog.TYPE_DECR);  // 积分变更类型. 0是减少 1是增加
        accountLogMapper.insert(accountLog);
        // 2 减少积分)
        int count = usableIntegralMapper.decrIntergral(operateIntergralVo.getUserId(),operateIntergralVo.getValue());
        if (count == 0) {
            // 操作积分不足
            throw new BusinessException(IntergralCodeMsg.INTERGRAL_NOT_ENOUGH);
        }
    }

    @Override
    public void decrIntergralTry(OperateIntergralVo operateIntergralVo, BusinessActionContext context) {
        log.info("进入try");
        // 将减掉的积分存入冻结积分中
        int freezeIntergral = usableIntegralMapper.freezeIntergral(operateIntergralVo.getUserId(), operateIntergralVo.getValue());
        if (freezeIntergral == 0) {
            throw new BusinessException(IntergralCodeMsg.INTERGRAL_NOT_ENOUGH);
        }
        commonInsertAccountTransaction(operateIntergralVo,context,AccountTransaction.STATE_TRY,AccountTransaction.DECR_TYPE);

    }

    @Override
    public void decrIntergralCommit(BusinessActionContext context) {
        log.info("进入confirm");
        // 查询日志表数据
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            log.info("异常情况");
        }

        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            // 执行confirm 逻辑
            Object objJson = context.getActionContext("operateIntergralVo");
            OperateIntergralVo operateIntergralVo = JSON.parseObject(objJson + "", OperateIntergralVo.class);
            // 减积分
            usableIntegralMapper.decrIntergral(operateIntergralVo.getUserId(), operateIntergralVo.getValue());
            // 释放积分
            usableIntegralMapper.unFreezeIntergral(operateIntergralVo.getUserId(),operateIntergralVo.getValue());
            // 修改状态为已提交状态
            accountTransactionMapper.updateAccountTransactionState(context.getXid(),context.getBranchId()+"",AccountTransaction.STATE_COMMIT,AccountTransaction.STATE_TRY);
        } else if (AccountTransaction.STATE_COMMIT.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }
    }

    @Override
    public void decrIntergralRollback(BusinessActionContext context) {
        log.info("进入cancel");
        // 查询日志表数据
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            // 往表里面插入一条数据
            Object objJson = context.getActionContext("operateIntergralVo");
            OperateIntergralVo operateIntergralVo = JSON.parseObject(objJson + "", OperateIntergralVo.class);
            commonInsertAccountTransaction(operateIntergralVo,context,AccountTransaction.STATE_CANCEL,AccountTransaction.DECR_TYPE);
            return;
        }

        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            // 执行cancel 操作
            // 把状态修改成已回滚
            accountTransactionMapper.updateAccountTransactionState(context.getXid(),context.getBranchId()+"",AccountTransaction.STATE_CANCEL,AccountTransaction.STATE_TRY);
            // 释放积分
            Object objJson = context.getActionContext("operateIntergralVo");
            OperateIntergralVo operateIntergralVo = JSON.parseObject(objJson + "", OperateIntergralVo.class);
            usableIntegralMapper.unFreezeIntergral(operateIntergralVo.getUserId(),operateIntergralVo.getValue());
        } else if (AccountTransaction.STATE_CANCEL.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }
    }

    @Override
    @Transactional
    public void incrIntergral(OperateIntergralVo operateIntergralVo) {
        // 1 插入流水记录
        AccountLog accountLog = new AccountLog();
        accountLog.setAmount(operateIntergralVo.getValue()); // 此次积分变动数值
        accountLog.setGmtTime(new Date());                   // 日志插入时间
        accountLog.setInfo(operateIntergralVo.getInfo());    // 备注信息
        accountLog.setPkValue(operateIntergralVo.getPk());   // 业务主键
        accountLog.setType(AccountLog.TYPE_INCR);  // 积分变更类型. 0是减少 1是增加
        accountLogMapper.insert(accountLog);
        // 2 加积分操作
        usableIntegralMapper.addIntergral(operateIntergralVo.getUserId(),operateIntergralVo.getValue());
    }

    @Override
    public void incrIntergralTry(OperateIntergralVo operateIntergralVo, BusinessActionContext context) {
        log.info("进入try");
        commonInsertAccountTransaction(operateIntergralVo,context,AccountTransaction.STATE_TRY,AccountTransaction.INCR_TYPE);
    }

    public void commonInsertAccountTransaction(OperateIntergralVo operateIntergralVo, BusinessActionContext context,int state,String type) {
        AccountTransaction accountTransaction = new AccountTransaction();
        accountTransaction.setActionId(context.getBranchId() +""); //分支事务ID
        accountTransaction.setAmount(operateIntergralVo.getValue()); //此次积分变更数值
        accountTransaction.setGmtCreated(new Date()); //事务日志记录创建时间
        accountTransaction.setGmtModified(new Date()); //事务日志记录修改时间
        accountTransaction.setTxId(context.getXid()); //全局事务ID
        accountTransaction.setUserId(operateIntergralVo.getUserId());  // 用户ID
        accountTransaction.setState(state);  //事务状态
        accountTransaction.setType(type); //此次积分变更类型 0减少积分 1增加积分
        accountTransactionMapper.insert(accountTransaction);
    }

    @Override
    public void incrIntergralCommit(BusinessActionContext context) {
        log.info("进入confirm");
        // 查询日志表数据
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            log.info("异常情况");
        }

        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            // 执行confirm 逻辑
            Object objJson = context.getActionContext("operateIntergralVo");
            OperateIntergralVo operateIntergralVo = JSON.parseObject(objJson + "", OperateIntergralVo.class);
            usableIntegralMapper.addIntergral(operateIntergralVo.getUserId(),operateIntergralVo.getValue());
            // 修改状态为已提交状态
            accountTransactionMapper.updateAccountTransactionState(context.getXid(),context.getBranchId()+"",AccountTransaction.STATE_COMMIT,AccountTransaction.STATE_TRY);
        } else if (AccountTransaction.STATE_COMMIT.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }
    }

    @Override
    public void incrIntergralRollback(BusinessActionContext context) {
        log.info("进入cancel");
        // 查询日志表数据
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            // 往表里面插入一条数据
            Object objJson = context.getActionContext("operateIntergralVo");
            OperateIntergralVo operateIntergralVo = JSON.parseObject(objJson + "", OperateIntergralVo.class);
            commonInsertAccountTransaction(operateIntergralVo,context,AccountTransaction.STATE_CANCEL,AccountTransaction.INCR_TYPE);
        }

        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            // 执行cancel 操作
            // 把状态修改成已回滚
            accountTransactionMapper.updateAccountTransactionState(context.getXid(),context.getBranchId()+"",AccountTransaction.STATE_CANCEL,AccountTransaction.STATE_TRY);
        } else if (AccountTransaction.STATE_CANCEL.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }
    }
}
